import { MEMORY_TEST_CONFIG, MEMORY_TEST_RATINGS } from '../constants/memoryTest';
import { MemoryTestRating, MemoryTestStats, GridItem } from '../types/memoryTest';
import { TestResult } from '../types';

export const generateSequence = (currentLevel: number): number[] => {
  const sequenceLength = Math.min(currentLevel + 2, MEMORY_TEST_CONFIG.MAX_SEQUENCE_LENGTH);
  const newSequence: number[] = [];
  const totalCells = MEMORY_TEST_CONFIG.GRID_SIZE * MEMORY_TEST_CONFIG.GRID_SIZE;
  const availablePositions = Array.from({ length: totalCells }, (_, i) => i);

  for (let i = 0; i < sequenceLength; i++) {
    const randomIndex = Math.floor(Math.random() * availablePositions.length);
    const position = availablePositions[randomIndex];
    newSequence.push(position);
    availablePositions.splice(randomIndex, 1);
  }

  return newSequence;
};

export const calculateMemorizeTime = (currentLevel: number): number => {
  const sequenceLength = Math.min(currentLevel + 2, MEMORY_TEST_CONFIG.MAX_SEQUENCE_LENGTH);
  return MEMORY_TEST_CONFIG.BASE_MEMORIZE_TIME + Math.floor(sequenceLength / 2);
};

export const createInitialGrid = (): GridItem[] => {
  const totalCells = MEMORY_TEST_CONFIG.GRID_SIZE * MEMORY_TEST_CONFIG.GRID_SIZE;
  return Array.from({ length: totalCells }, (_, index) => ({
    id: index,
    isHighlighted: false,
    isSelected: false
  }));
};

export const calculateLevelScore = (userSequence: number[], correctSequence: number[]): number => {
  if (correctSequence.length === 0) return 0;
  
  const correctCount = userSequence.filter((id, index) => id === correctSequence[index]).length;
  const score = Math.round((correctCount / correctSequence.length) * 100);
  return Math.max(0, Math.min(100, isNaN(score) ? 0 : score));
};

export const calculateAverageScore = (scores: number[]): number => {
  if (scores.length === 0) return 0;
  const sum = scores.reduce((a, b) => a + b, 0);
  const avg = sum / scores.length;
  return Math.round(isNaN(avg) ? 0 : Math.max(0, Math.min(100, avg)));
};

export const calculateFinalScore = (scores: number[], currentLevel: number): number => {
  const avgScore = calculateAverageScore(scores);
  const levelBonus = Math.max(0, (currentLevel - 1) * MEMORY_TEST_CONFIG.LEVEL_BONUS_MULTIPLIER);
  const finalScore = avgScore + levelBonus;
  return Math.round(isNaN(finalScore) ? 0 : Math.max(0, Math.min(100, finalScore)));
};

export const getRating = (finalScore: number): MemoryTestRating => {
  const rating = MEMORY_TEST_RATINGS.find(r => finalScore >= r.minScore);
  return rating || MEMORY_TEST_RATINGS[MEMORY_TEST_RATINGS.length - 1];
};

export const updateGridWithCorrectness = (
  grid: GridItem[], 
  userSequence: number[], 
  correctSequence: number[]
): GridItem[] => {
  return grid.map(cell => {
    const userIndex = userSequence.indexOf(cell.id);
    const correctIndex = correctSequence.indexOf(cell.id);
    
    if (userIndex !== -1) {
      return {
        ...cell,
        isCorrect: userIndex === correctIndex && correctIndex !== -1
      };
    }
    return cell;
  });
};

export const shouldCompleteTest = (currentLevel: number, score: number): boolean => {
  return currentLevel >= MEMORY_TEST_CONFIG.MAX_LEVELS || score < MEMORY_TEST_CONFIG.FAILURE_THRESHOLD;
};

export const createTestResult = (
  scores: number[],
  currentLevel: number,
  testStartTime: number,
  memorizeTime: number
): TestResult => {
  const finalScore = calculateFinalScore(scores, currentLevel);
  const avgScore = calculateAverageScore(scores);
  const levelsCompleted = Math.max(0, currentLevel - 1);
  const totalTestTime = testStartTime > 0 ? Math.round((Date.now() - testStartTime) / 1000) : 0;
  
  const details: MemoryTestStats = {
    levelsCompleted: levelsCompleted,
    averageAccuracy: avgScore,
    levelScores: [...scores],
    maxLevel: currentLevel,
    totalSequences: scores.length,
    perfectLevels: scores.filter(score => score === 100).length,
    rating: getRating(finalScore).text,
    memorizeTimeUsed: memorizeTime,
    
    // 兼容性字段
    totalQuestions: scores.length,
    correctAnswers: scores.filter(score => score >= 70).length, // 70%以上视为正确
    averageTimePerQuestion: totalTestTime > 0 && scores.length > 0 ? Math.round(totalTestTime / scores.length) : 0,
    
    // 记忆测试特有字段
    averageTime: totalTestTime,
    totalRounds: scores.length,
    difficulty: currentLevel
  };

  return {
    id: Date.now().toString(),
    testType: 'memory',
    score: finalScore,
    completedAt: new Date(),
    duration: Math.max(1, totalTestTime),
    details
  };
};